home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Programming / Programming Tools / Pascal Demos from Apple / edit / TEXTEDIT.TEXT next >
Encoding:
Text File  |  1985-05-13  |  13.8 KB  |  432 lines  |  [TEXT/ttxt]

  1. {$X-}   {Turn off stack expansion. This is a Lisa concept, not needed on Mac}
  2. {$U-}   {Turn off the Lisa Libraries. This is required by the WorkShop}
  3. {$R-}   {Turn off range checking}
  4.  
  5. PROGRAM TextThings;
  6.  
  7. {Jeffery J. Bradford    Macintosh Technical Support  April 1985 }
  8.  
  9. { This example shows you how to use the TextEdit routines to enter, delete}
  10. { and manipulate text. For more information on handling text look at the  }
  11. { example called EDIT and for scrolling look at the SCROLLING.TEXT example}
  12. { If you need more versitality in manipulating text look into the Munger  }
  13. { utility located in the ToolBox Utility Section.                         }
  14.  
  15. {  Specifics of this example are:                                         }
  16. {     Entering text;                                                      }
  17. {     Simple auto-scrolling routine                                       }
  18. {     Changing cursor to an I-Beam when in view rectangle;                }
  19. {     Setup Menus & Command Keys for Cutting, Copying, & Pasting text;    }
  20.  
  21.  
  22. USES
  23.     {$U Obj/Memtypes  } MemTypes,
  24.     {$U Obj/QuickDraw } QuickDraw,
  25.     {$U Obj/OSIntf    } OSIntf,
  26.     {$U Obj/ToolIntf  } ToolIntf,
  27.     {$U Obj/PackIntf  } PackIntf;
  28.  
  29. CONST
  30. {menu stuff}
  31.     AppleMenu = 256;
  32.     FileMenu  = 257;
  33.     EditMenu  = 258;
  34.  
  35. {text edit scrolling stuff}
  36.     maxViewLines = 7;           {max lines that can be viewed}
  37.  
  38. {window IDs}
  39.     WindResID = 256;
  40.  
  41. TYPE
  42. {this is useful stuff you might need sometime}
  43.  
  44.     WordStuff = Packed Record
  45.        Case Integer of
  46.          0: (Word: Integer);
  47.          1: (SByte1,SByte0: SignedByte);
  48.          2: (b15,b14,b13,b12,b11,b10,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0: Boolean)
  49.        End;
  50.  
  51.     CharStuff = Packed Record
  52.          chr3,chr2,chr1,chr0: char;
  53.        End;
  54.  
  55.     LMwordPtr = ^Integer;          {pointer to low memory address}
  56.     LMLongPtr = ^LongInt;          {pointer to low memory address - long}
  57.  
  58.  
  59.  
  60. VAR
  61. {global program stuff}
  62.     Finished:      Boolean;    {used to terminate the program}
  63.     ClockCursor:   CursHandle; {handle to the waiting watch cursor}
  64.     TextCursor:    CursHandle; {handle to the I - beam text entry cursor}
  65.  
  66. {text edit stuff}
  67.     TextHandle: TEHandle;    {handle to the text record where all text is kept}
  68.     DestRect:   Rect;        {Text view rect, used for updating}
  69.     TextFrame:  Rect;        {holds the frame around the text}
  70.     LastLine:   Integer;     {holds the last line showing on screen}
  71.  
  72. {Screen stuff}
  73.     DragArea:   Rect;          {holds the area where window can be dragged in}
  74.     GrowArea:   Rect;          {holds the area to which a window's size can change}
  75.     Screen:     Rect;          {holds the screen dimensions}
  76.  
  77. {Window stuff}
  78.     TextWindow:   WindowPtr;    {pointer to the first window}
  79.  
  80. {-----------------------------------------------------------------------------
  81.                      end of global variable definition
  82. -----------------------------------------------------------------------------}
  83.  
  84. PROCEDURE FrameText;
  85. Begin
  86.   FrameRect(TextFrame);
  87. End;
  88.  
  89. {-----------------------------------------------------------------------------}
  90.  
  91. PROCEDURE ChangeCursorForText;
  92. Var MousePt: Point;
  93. Begin
  94.   If TextWindow = FrontWindow then        {is it our window}
  95.   begin
  96.     GetMouse(MousePt);                    {get the mouse location}
  97.     If PtinRect(MousePt,TextFrame)        {is it in the text view rect??}
  98.        then SetCursor(TextCursor^^)       {if so set cursor to I-beam}
  99.        else SetCursor(arrow);             {else make it an arrow}
  100.   end;
  101. End;
  102.  
  103. {-----------------------------------------------------------------------------}
  104.  
  105. PROCEDURE Scroll_ifNecessary(TxHdl:TEHandle);
  106. {This is a very simple scrolling routine. Look at example/File.text or}
  107. {one of the scrolling examples for more information. For this to work }
  108. {better, check to see if the RETURN key was pressed along w/new lines.}
  109.  
  110. Var numLines: integer;     {number of lines in the text record}
  111.     LnHeight: integer;     {line height of the font}
  112.  
  113. Begin
  114.   numLines := TxHdl^^.nLines;
  115.   LnHeight := TxHdl^^.LineHeight;
  116.  
  117.     If numLines >= maxViewLines then      {if text lines > 5 start checking}
  118.     begin
  119.        If numLines > LastLine then     {if lines > last count then scroll down}
  120.        begin
  121.          TEScroll(0,-LnHeight,TxHdl);
  122.          LastLine := LastLine + 1;
  123.        end;
  124.  
  125.        If numLines < LastLine then     {if lines < last count scroll up}
  126.        begin
  127.          TEScroll(0,+LnHeight,TxHdl);
  128.          LastLine := LastLine - 1;
  129.        end;
  130.     end;
  131. End;
  132.  
  133. {-----------------------------------------------------------------------------}
  134.  
  135. PROCEDURE ProcessMenu_in(CodeWord:longint);
  136. Var
  137.   Menu_No:    integer;        {menu number that was selected}
  138.   Item_No:    integer;        {item in menu that was selected}
  139.   NameHolder: Str255;         {name holder for desk accessory or font}
  140.   DNA:        integer;        {OpenDA will never return 0, so don't care}
  141.  
  142. Begin
  143.   If CodeWord <> 0 then {go ahead and process the command}
  144.   begin
  145.     Menu_No := HiWord(CodeWord);   {get the Hi word of...}
  146.     Item_no := LoWord(CodeWord);   {get the Lo word of...}
  147.  
  148.     Case Menu_No of
  149.  
  150.      AppleMenu: Begin
  151.                   GetItem(GetMHandle(AppleMenu), Item_No, NameHolder);
  152.                   DNA := OpenDeskAcc(NameHolder);
  153.                 End;
  154.  
  155.       FileMenu: Begin
  156.                   Case Item_No of
  157.                     1: Finished := True;          {quit}
  158.                   End;
  159.                 End;
  160.  
  161.       EditMenu: Begin
  162.                   If Not SystemEdit(Item_no - 1) {if not for a desk accessory}
  163.                   then
  164.                     Case Item_No of
  165.                       1: begin end;               {undo}
  166.                     { 2:                           line divider}
  167.                       3: TECut  (TextHandle);
  168.                       4: TECopy (TextHandle);
  169.                       5: TEPaste(TextHandle);
  170.                     End;
  171.                 End;
  172.  
  173.     End;{case of Menu_No}
  174.  
  175.     HiliteMenu(0);               {unhilite after processing menu}
  176.   end; {the If codeword <> 0}
  177. End; {of ProcessMenu_in procedure}
  178.  
  179.  
  180. {-------------------------------------------------------------------}
  181. {----- These are procedures called from the main event loop  -------}
  182.  
  183. PROCEDURE DealwthMouseDowns(Event:EventRecord);
  184. Var Location: integer;
  185.     WindowPointedTo: WindowPtr;
  186.     MouseLoc:Point;
  187.     WindoLoc:integer;
  188. Begin
  189.   MouseLoc := Event.Where;
  190.   WindoLoc := FindWindow(MouseLoc, WindowPointedTo);
  191.   Case WindoLoc of
  192.  
  193.      inMenuBar: ProcessMenu_in(MenuSelect(MouseLoc));
  194.  
  195.      inSysWindow: SystemClick(Event,WindowPointedTo);
  196.  
  197.      inContent: If WindowPointedTo <> FrontWindow
  198.                 then SelectWindow(WindowPointedTo)
  199.                 else begin
  200.                        GlobaltoLocal(MouseLoc);
  201.                        TEClick(MouseLoc, False, TextHandle);
  202.                      end;
  203.  
  204.      inGrow:    If WindowPointedTo <> FrontWindow
  205.                 then SelectWindow(WindowPointedTo)
  206.                 else begin {ReSizeWindow(WindowPointedTo,MouseLoc);} end;
  207.  
  208.      inDrag   :DragWindow(WindowPointedTo,MouseLoc,DragArea);
  209.  
  210.      inGoAway :If TrackGoAway(WindowPointedTo,MouseLoc) then
  211.                begin
  212.                  HideWindow(WindowPointedTo);
  213.                end;
  214.  
  215.   End{ of case};
  216. End;
  217.  
  218. {-----------------------------------------------------------------------------}
  219.  
  220. PROCEDURE DealwthKeyDowns(Event:EventRecord);
  221. Var CharCode:char;
  222. Begin
  223.    CharCode:= CharStuff(Event.message).Chr0; {get low byte w/no processing}
  224.  
  225.   If BitAnd(Event.modifier,CmdKey) = CmdKey
  226.    then
  227.      begin  {key board command - probably a menu command}
  228.        ProcessMenu_in(MenuKey(CharCode));
  229.      end
  230.    else
  231.      begin
  232.        TEKey(CharCode, TextHandle);
  233.        Scroll_ifNecessary(TextHandle);
  234.      end;
  235. End;
  236.  
  237. {-----------------------------------------------------------------------------}
  238.  
  239. PROCEDURE DealwthActivates(Event: EventRecord);
  240. Var TargetWindow:WindowPtr;
  241. Begin
  242.    TargetWindow := WindowPtr(Event.message);
  243.  {  DrawGrowIcon(TargetWindow);  this window doesn't have one}
  244.  
  245.    If Odd(Event.modifiers) {then the window is becoming active}
  246.    then
  247.      begin
  248.        SetPort(TargetWindow);
  249.        TEActivate(TextHandle);
  250.      end
  251.    else
  252.      begin
  253.        TEDeactivate(TextHandle);
  254.      end;
  255. End;
  256.  
  257. {-----------------------------------------------------------------------------}
  258.  
  259. PROCEDURE DealwthUpdates(Event:EventRecord);
  260. Var UpDateWindow:  WindowPtr;
  261.         TempPort:  WindowPtr;
  262. Begin
  263.    UpDateWindow := WindowPtr(Event.message);
  264.    GetPort(TempPort);                {Save the current port}
  265.  
  266.    SetPort    (UpDateWindow);      {set the port to one in Evt.msg}
  267.    BeginUpDate(UpDateWindow);
  268. {     EraseRect(UpDateWindow^.VisRgn^^.rgnBBox);}
  269.      TEUpDate (DestRect, TextHandle);
  270.      FrameText;
  271.    EndUpDate  (UpDateWindow);
  272.  
  273.    SetPort    (TempPort);             {restore to the previous port}
  274. End;
  275.  
  276. {-----------------------------------------------------------------------------}
  277.  
  278. PROCEDURE MainEventLoop;
  279. Var Event:EventRecord;
  280.     ProcessIt: Boolean;
  281. Begin
  282.   Repeat
  283.     SystemTask;             {so you can support Desk Accessories}
  284.     ChangeCursorForText;    {change cursor to I-Beam in text window}
  285.     TEIdle(TextHandle);     {make insertion caret blink}
  286.  
  287.     ProcessIt := GetNextEvent(EveryEvent,Event);
  288.     If ProcessIt{is true} then {we'll ProcessIt}
  289.       Case Event.what of
  290.  
  291.         mouseDown  : DealwthMouseDowns(Event);
  292.         AutoKey    : DealwthKeyDowns  (Event);
  293.         KeyDown    : DealwthKeyDowns  (Event);
  294.         ActivateEvt: DealwthActivates (Event);
  295.         UpDateEvt  : DealwthUpdates   (Event);
  296.  
  297.       End;{of Case}
  298.   Until Finished; {terminate the program}
  299. End;
  300.  
  301. {-----------------------------------------------------------------------------}
  302.  
  303. PROCEDURE InitThings;
  304. Begin
  305.   InitGraf(@thePort);          {create a grafport for the screen}
  306.  
  307.   MoreMasters;                 {extra pointer blocks at the bottom of the heap}
  308.   MoreMasters;                 {this is 5 X 64 master pointers}
  309.   MoreMasters;
  310.   MoreMasters;
  311.   MoreMasters;
  312.  
  313. {get the cursors we use and lock them down - no clutter}
  314.   ClockCursor := GetCursor(watchCursor);
  315.   TextCursor  := GetCursor(iBeamCursor);
  316.   HLock(Handle(ClockCursor));
  317.   HLock(Handle(TextCursor));
  318.  
  319. {show the watch while we wait for inits & setups to finish}
  320.   SetCursor(ClockCursor^^);
  321.  
  322. {init everything in case the app is the Startup App}
  323.   InitFonts;                     {startup the fonts manager}
  324.   InitWindows;                   {startup the window manager}
  325.   InitMenus;                     {startup the menu manager}
  326.   TEInit;                        {startup the text edit manager}
  327.   InitDialogs(Nil);              {startup the dialog manager}
  328.  
  329.   Finished := False;             {set program terminator to false}
  330.   FlushEvents(everyEvent,0);     {clear events from previous program}
  331. End;
  332.  
  333. {-----------------------------------------------------------------------------}
  334.  
  335. PROCEDURE SetupLimits;
  336. Begin
  337.   Screen := ScreenBits.Bounds;   {set the size of the screen}
  338.   SetRect(DragArea,Screen.left+4,Screen.top+24,Screen.right-4,Screen.bottom-4);
  339.   SetRect(GrowArea,Screen.left,Screen.top+24,Screen.right,Screen.bottom);
  340. End;
  341.  
  342. {-----------------------------------------------------------------------------}
  343.  
  344. PROCEDURE SetupMenus;
  345. Var
  346.   MenuTopic: MenuHandle;
  347. Begin
  348.   MenuTopic := GetMenu(AppleMenu);  {get the apple desk accessories menu}
  349.   AddResMenu(MenuTopic,'DRVR');     {adds all names into item list}
  350.   InsertMenu(MenuTopic,0);          {put in list held by menu manager}
  351.  
  352.   MenuTopic := GetMenu(FileMenu);   {always need this for Quiting}
  353.   InsertMenu(MenuTopic,0);
  354.  
  355.   MenuTopic := GetMenu(EditMenu);   {always need for editing Desk Accessories}
  356.   InsertMenu(MenuTopic,0);
  357.  
  358.   DrawMenuBar;           {all done so show the menu bar}
  359. End;
  360.  
  361. {-----------------------------------------------------------------------------}
  362.  
  363. PROCEDURE SetupWindows;
  364. Begin
  365.   TextWindow :=  GetNewWindow(WindResID, Nil, POINTER(-1)); {get windo resource}
  366. End;
  367.  
  368. {-----------------------------------------------------------------------------}
  369.  
  370. PROCEDURE SetupTextEdit;
  371. Var LineHt:    Integer;
  372.     FontStuff: FontInfo;
  373.     ViewRect:  Rect;
  374. Begin
  375.   SetPort(TextWindow);                     {ActEvt has not occured, so set it}
  376.  
  377.   TextFont(Venice);                        {this is the font we'll use}
  378.   TextSize(12);                            {this is the size we'll use}
  379.   GetFontInfo(FontStuff);                  {get its specifics}
  380.  
  381. {get the lineheight for the font}
  382.   LineHt := FontStuff.ascent + FontStuff.descent + FontStuff.leading;
  383.   LineHt := (LineHt+1) * (MaxViewLines+1);
  384.  
  385.   SetRect(ViewRect,10,10,135,LineHt);      {initialize DestRect}
  386.   TextFrame := ViewRect;                   {rect for framing the text}
  387.   InSetRect(TextFrame, -1,-1);             {make it a little larger}
  388.   DestRect := ViewRect;                    {make the DestRect the same}
  389.  
  390.   InSetRect(DestRect,9,0);                 {make Rect smaller by 2 pixels }
  391.  
  392.   TextHandle := TENew(DestRect, ViewRect); {allocate a text record for the text}
  393.  
  394.   TextHandle^^.txFont := Venice;           {set the font}
  395.   TextHandle^^.txSize := 12;               {set the font size}
  396.  
  397.   LastLine := maxViewLines;                {start scrolling after max text lines}
  398. End;
  399.  
  400. {-----------------------------------------------------------------------------}
  401.  
  402. PROCEDURE SetUpThings;
  403. Begin
  404.   SetupWindows;         {do first so its low in heap}
  405.   SetupMenus;
  406.   SetupTextEdit;
  407.   SetupLimits;
  408.  
  409.   InitCursor;           {ready to go, so show the Arrow cursor}
  410. End;
  411.  
  412. {-----------------------------------------------------------------------------}
  413.  
  414. PROCEDURE CloseThings;
  415. Begin
  416. {close files, if you changed sys resources, UNchange them here be carefull}
  417. {about changing sys things, remember the Switcher could be around}
  418.  
  419. {why put these here??? who knows everything is gone anyway}
  420.    TEDispose(TextHandle);          {get rid of TextEdit stuff}
  421.    DisposeWindow(TextWindow);      {since W mgr allocated space}
  422. End;
  423.  
  424. {-----------------------------------------------------------------------------}
  425.  
  426. BEGIN
  427.   InitThings;
  428.   SetUpThings;
  429.   MainEventLoop;
  430.   CloseThings;
  431. END.
  432.